<?php
namespace cubox\provider\template;

use cubox\File;
use cubox\Webpack;

class Asset
{
    public static array $fileList = [];
    
    private string $webpackUrl = '';
    private string $html = '';
    private string $name = '';
    private string $file = '';

    public function __construct(string $name,string $html,string $file,string $webpackUrl)
    {
        $this->html = $html;
        $this->webpackUrl = $webpackUrl;
        $this->file = $file;
        $this->name = $name;
    }

    public function make():string{
        $html = $this->html;

        if (pathinfo($this->file,PATHINFO_EXTENSION)!='css'){
            $html = $this->compile($html,'link','href');
            $html = $this->compile($html,'script','src');
            $html = $this->compile($html,'img','src');

            //<style></style>
            $list = Tag::parse($html,'style');
            foreach($list as $item){
               if ($item['content']!='') $html =  str_replace($item['input'],$this->compileImageUrl($item['input']),$html);
            }

        }else{
            $html = $this->compileImageUrl($html);
        }

        return $html;
    }

    protected function compile($html,$tag,$dataName):string{
        $data = Tag::parse($html,$tag);
        
        if (count($data)>0){
            foreach($data as  $item){
               
                if (isset($item['param'][$dataName])  && $item['param'][$dataName]!=''){
                    
                    $url = $item['param'][$dataName];

                    $oldUrl = $url;
                    $marks = "";
                    if (substr($url,0,1)=="'" || substr($url,0,1)=='"'){
                        $marks  = substr($url,0,1);
                        $url = substr($url,1,strlen($url)-2);
                    }

                    $param = "";
                    if (strpos($url,'?')!==false){
                        $param = substr($url,strpos($url,'?')+1,strlen($url)-strpos($url,'?')-1);
                        $url = substr($url,0,strpos($url,'?'));
                    }


                    $file = self::compileFile(dirname($this->file),$url);
                    if ($url!=$file){
                        switch(pathinfo($file,PATHINFO_EXTENSION)){
                            case 'css':
                                $obj = Webpack::fileDriver($this->name,$file,$this->webpackUrl);
                                $obj->pack();
                                $html =  str_replace($item['input'],'',$html);
                                break;
                            case 'js':
                                Webpack::addScript($this->name,file_get_contents($file));
                                $html =  str_replace($item['input'],'',$html);       
                                break;
                            default:
                                
                                $input = str_replace($url,self::url($this->webpackUrl,$file),$item['input']);
                                $html =  str_replace($item['input'],$input,$html);       
                            break;
                        }
                    }


                    
                    
                } 
            }
        }

        return $html;
    
    }


    protected function compileImageUrl($content){
        
        $re = '/url\(([\s\S]*?)\)/i';
        preg_match_all ($re, $content, $match);
        $image_url_data = $match[1];
        if ($image_url_data){
            foreach($image_url_data as $url){
                $oldUrl = $url;
                $marks = "";
                if (substr($url,0,1)=="'" || substr($url,0,1)=='"'){
                    $marks  = substr($url,0,1);
                    $url = substr($url,1,strlen($url)-2);
                }

                $param = "";
                if (strpos($url,'?')!==false){
                    $param = substr($url,strpos($url,'?')+1,strlen($url)-strpos($url,'?')-1);
                    $url = substr($url,0,strpos($url,'?'));
                }
                 
                $file = self::compileFile(dirname($this->file),$url);
                if ($file!=$url){
                    $new_url = self::url($this->webpackUrl,$file);
                    if (!self::base64Data($new_url) && $param!=''){
                        $new_url .="?".$param;
                    }
                    
                    $content =  str_replace($oldUrl,$marks.$new_url.$marks,$content);
                }
            }
        }
        return $content;
    }

    public static function compileFile(string $dir,string $url){
        $skip = array('http://','https://','data:','/','#','javascript');
        
        $not_replace = false;
        
        foreach($skip as $k){
            if (substr($url,0,strlen($k))==$k){  
                $not_replace =  true;
            }
        }

        if ($not_replace) return $url;


        $arr = explode('/',$url);
 
        $new_arr = array();
        //$new_sum = 0;
        $up_folder_number = 0;
        $up_lab = true;

        foreach($arr as $v){
            if ($v=='..' && $up_lab){
                $up_folder_number ++;
            }else{
                $up_lab = false;
                $new_arr[] = $v;
            }
        }
        $base_url =  str_replace('\\','/',$dir);
        $base_url_arr = explode('/',$base_url);

        $base_url_arr = array_slice($base_url_arr,0,count($base_url_arr)-$up_folder_number);
        $file = implode('/',array_merge($base_url_arr,$new_arr));
        return   File::cleanPath($file);
    }
    

    public static function url(string $webpackUrl,string $file){
        
        if (isset(self::$fileList[$file])) return self::$fileList[$file];

        if (file_exists($file)){
            $ext = pathinfo($file,PATHINFO_EXTENSION);
            if (self::isImage($file)){
                $size = filesize($file);
                if ($size<1024*10){
                    $base64 = base64_encode(file_get_contents($file));
                    $base64 = 'data:'.self::base64Type($ext).';base64,'.$base64;
                    self::$fileList[$file] = $base64;
                    return $base64;
                }
            }

            $webpackFileName = 'asset.'.md5($file).'.'.$ext;
            //复制图片
            $webpackFilePath = RUN.DS.WEBPACK.DS.$webpackFileName;
            if (!file_exists($webpackFilePath)){
                copy($file,$webpackFilePath);
            }
            self::$fileList[$file] = $webpackUrl.'/'.$webpackFileName;

            return $webpackUrl.'/'.$webpackFileName;
            //
        }else{
            return 'file not exists '.$file;
        }
    }

    public static function isImage($file){
        $arr = array('jpg','jpeg','png','gif','bmp','svg');
        $ext = strtolower(pathinfo($file,PATHINFO_EXTENSION));
        return in_array($ext,$arr);
    }

    private static function base64Data($str){
        return substr($str,0,5)=='data:';
    }
    
    private static function base64Type($ext){
        $arr = array('jpg'=>'image/jpeg','jpeg'=>'image/jpeg','png'=>'image/png','gif'=>'image/gif','bmp'=>'image/bmp','svg'=>'image/svg+xml');
        return $arr[$ext];
    }

}